#include "StatusServer.h"
#include "../ConfigMgr.h"
#include "../log.h"
#include "../NetGlobal.h"

#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <mutex>
#include <string>
#include <utility>

std::string generateUniqueString()
{
    // 创建boost UUID对象
    boost::uuids::uuid uuid = boost::uuids::random_generator()();
    // 将UUID转换为字符串
    return boost::uuids::to_string(uuid);

    // 生成随机字符串
    std::string random_string = boost::uuids::to_string(boost::uuids::random_generator()());
    return random_string;
}



StatusServerImpl::StatusServerImpl()
{
    auto config = ConfigMgr::GetConfig();

    ChatServer server;
    server.host = config->GateServerInfo_01.IP;
    server.port = std::to_string(config->GateServerInfo_01.Port);
    server.name = config->GateServerInfo_01.Name;
    server.cur_load = 0;
    _server_map[server.name] = server;
    log_info("Add ChatServer: {}:{} Name: {}", server.host, server.port, server.name);

    server.host = config->GateServerInfo_02.IP;
    server.port = std::to_string(config->GateServerInfo_02.Port);
    server.name = config->GateServerInfo_02.Name;
    server.cur_load = 0;
    _server_map[server.name] = server;
    log_info("Add ChatServer: {}:{} Name: {}", server.host, server.port, server.name);
}

Status StatusServerImpl::GetChatServer(ServerContext* context, const GetChatServerReq* request, GetChatServerRsp* reply)
{
    const ChatServer& server = _GetChatServer();
    log_info("GetChatServer, server: {}:{}", server.host, server.port);
    reply->set_host(server.host);
    reply->set_port(server.port);
    reply->set_code(ErrorCode::Success);
    reply->set_msg("success");
    reply->set_token(generateUniqueString());
    _InsertToken(request->uid(), reply->token());
    return Status::OK;
}

Status StatusServerImpl::Login(ServerContext* context, const LoginReq* request, LoginRsp* reply)
{
    auto uid = request->uid();
    auto token = request->token();
    
    {
        std::lock_guard<std::mutex> lock(_token_mutex);
        auto it = _tokens.find(uid);
        if (it == _tokens.end())
        {
            reply->set_code(ErrorCode::UserNotExists);
            reply->set_msg("user not exists");
            return Status::OK;
        }
        if (it->second != token)
        {
            reply->set_code(ErrorCode::UserTokenFailed);
            reply->set_msg("user token failed");
            return Status::OK;
        }
    }

    reply->set_code(ErrorCode::Success);
    reply->set_msg("success");
    reply->set_uid(uid);
    reply->set_token(token);

    return Status::OK;
}


ChatServer StatusServerImpl::_GetChatServer()
{
    std::lock_guard<std::mutex> lock(_server_mutex);
    // 寻找负载最小的服务器
    auto min_server = std::min_element(_server_map.begin(), _server_map.end(),
        [](const auto& a, const auto& b) {
            return a.second.cur_load < b.second.cur_load;
        });
    
    return min_server->second;
}

void StatusServerImpl::_InsertToken(uint32_t uid, const std::string& token)
{
    std::lock_guard<std::mutex> lock(_token_mutex);
    _tokens.insert(std::make_pair(uid, token));
}